#include "HeightMapTerrain.h"
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <SOIL.h>
#include <iostream>
using namespace std;

HeightMapTerrain::HeightMapTerrain(const char* hmapFile, const char* textureFile)
{
	int channels;
	unsigned char* imageData = SOIL_load_image(hmapFile, &m_X, &m_Z, &channels, SOIL_LOAD_L);

	GLuint texId = SOIL_load_OGL_texture
		(
		textureFile,
		SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID,
		SOIL_FLAG_MIPMAPS | /*SOIL_FLAG_INVERT_Y |*/ SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
		);

	std::cout << "Info : Terrain generation started\n";

	m_Mesh = new Mesh();
	SubMesh * subMesh = new SubMesh();

	for (int z = 0; z < m_Z; z++) {
		for (int x=0; x < m_X; x++) {
			VERTEX * vertex = new VERTEX;
			vertex->x = (float)(x - m_X/2)* 10;
			vertex->y = (float)(imageData[z * m_X + x]/256.f) * 200.f;
			vertex->z = (float)(z - m_Z/2)* 10;
			m_Mesh->addVertex(vertex);
		}
	}

	for (int z = 0; z < m_Z; z++) {
		for (int x=0; x < m_X; x++) {
			TEXCOORD * texCoord = new TEXCOORD;
			texCoord->s = x/(m_X*1.f);
			texCoord->t = z/(m_Z*1.f);
			m_Mesh->addTexCoord(texCoord);
		}
	}

	for (int z = 0; z < m_Z-1; z++) {
		for (int x=0; x < m_X-1; x++) {
			TRIANGLE * t1 = new TRIANGLE;
			t1->vIndex[0] = t1->tIndex[0] = z * m_X + x;
			t1->vIndex[1] = t1->tIndex[1] = (z+1) * m_X + x;
			t1->vIndex[2] = t1->tIndex[2] = z * m_X + (x+1);
			subMesh->addTriangle(t1);

			TRIANGLE * t2 = new TRIANGLE;
			t2->vIndex[0] = t2->tIndex[0] = (z+1) * m_X + x;
			t2->vIndex[1] = t2->tIndex[1] = z * m_X + (x+1);
			t2->vIndex[2] = t2->tIndex[2] = (z+1) * m_X + (x+1);
			subMesh->addTriangle(t2);
		}
	}
	subMesh->setTextureId(texId);
	m_Mesh->addSubMesh(subMesh);
	renderer = new Renderer(m_Mesh);

	std::cout << "Info : Terrain generation completed\n";
}

HeightMapTerrain::~HeightMapTerrain(void)
{
}

int HeightMapTerrain::getWidth()
{
	return m_X;
}

int HeightMapTerrain::getLength()
{
	return m_Z;
}

void HeightMapTerrain::render()
{
	glPushMatrix();
	glTranslatef(0, -100.f, 0);
	renderer->render();
	glPopMatrix();
}